<template>
  <div class="config-container">
    <el-form ref="form" :model="form">
      <el-card class="box-card">
        <div slot="header" class="config-header clearfix">
          <el-select
            v-model="way"
            size="mini"
            placeholder="请选择"
            :disabled="!manualModel"
            style="width: 110px;margin-right: 8px;"
            @change="onWayChange"
          >
            <el-option label="模板方式" :value="1" />
            <el-option label="手动方式" :value="2" />
          </el-select>

          <upload v-show="isTplWay" @on-succeed="onUploadSucceed" />

          <div v-show="isTplWay" class="header__item">
            <span class="label">模板名称</span>
            <el-input v-model="form.name" size="mini" />
          </div>
          <div v-show="isTplWay" class="header__item">
            <span class="label">报表类型</span>
            <el-select v-model="form.type" size="mini" placeholder="请选择">
              <el-option
                v-for="item in optionsOfReportType"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </div>
          <div class="header__right">
            <el-button :disabled="!form.excelId" type="text">删除模板</el-button>
            <el-divider class="header-divider" direction="vertical" />
            <el-button type="text" @click="submitForm('form')">保存模板</el-button>
          </div>
        </div>
        <el-table :data="form.list" style="width: 100%">
          <el-table-column label="标准名称" width="140">
            <template slot-scope="scope">
              <span v-if="!scope.row.edit">{{ scope.row.standardCode | value2lable(optionsOfStandardCode) }}</span>
              <el-select v-else v-model="scope.row.standardCode" size="mini" placeholder="标准名称">
                <el-option v-for="item in optionsOfStandardCode" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </template>
          </el-table-column>

          <el-table-column v-if="isTplWay" label="坐标" width="240">
            <template slot-scope="scope">
              <div style="display: flex;" class="column-coordinate">
                <span v-if="!scope.row.edit">{{ scope.row.sheetName || '--' }}</span>
                <el-input v-else v-model="scope.row.sheetName" size="mini" placeholder="表名" style="flex: 2;" />
                <span v-if="!scope.row.edit">&nbsp;|&nbsp;{{ scope.row.axis || '--' }}</span>
                <el-input v-else v-model="scope.row.axis" size="mini" placeholder="行列" style="flex: 1;" />

                <i v-if="scope.row.edit" class="el-icon-thumb" @click="handleTagvClick(scope)" />
              </div>
            </template>
          </el-table-column>
          <el-table-column v-if="isTplWay" label="值" prop="value" width="100" />
          <el-table-column v-if="isTplWay" label="计算公式" width="140">
            <template slot-scope="scope">
              <span v-if="!scope.row.edit">{{ scope.row.expression || '--' }}</span>
              <el-input v-else v-model="scope.row.expression" size="mini" placeholder="计算公式" />
            </template>
          </el-table-column>

          <el-table-column label="位置信息" width="300">
            <template slot-scope="scope">
              <div style="display: flex;">
                <span v-if="!scope.row.edit">{{ scope.row.branch | value2lable(optionsOfBranch) }}</span>
                <el-select v-else v-model="scope.row.branch" size="mini" placeholder="分厂">
                  <el-option v-for="item in optionsOfBranch" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
                <span v-if="!scope.row.edit">&nbsp;|&nbsp;{{ scope.row.workshop | value2lable(optionsOfWorkshop(scope.row)) }}</span>
                <el-select v-else v-model="scope.row.workshop" size="mini" placeholder="车间">
                  <el-option v-for="item in optionsOfWorkshop(scope.row)" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
                <span v-if="!scope.row.edit">&nbsp;|&nbsp;{{ scope.row.workarea | value2lable(optionsOfWorkarea(scope.row)) }}</span>
                <el-select v-else v-model="scope.row.workarea" size="mini" placeholder="分区">
                  <el-option v-for="item in optionsOfWorkarea(scope.row)" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="设备" width="180">
            <template slot-scope="scope">
              <div style="display: flex;">
                <span v-if="!scope.row.edit">{{ scope.row.deviceName | value2lable(optionsOfDevices(scope.row)) }}</span>
                <el-select v-else v-model="scope.row.deviceName" size="mini" placeholder="设备名">
                  <el-option v-for="item in optionsOfDevices(scope.row)" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
                <span v-if="!scope.row.edit">&nbsp;|&nbsp;{{ scope.row.deviceCode || '--' }}</span>
                <el-input v-else v-model="scope.row.deviceCode" type="number" size="mini" placeholder="设备编号" />
              </div>
            </template>
          </el-table-column>
          <el-table-column label="时间序" width="260">
            <template slot-scope="scope">
              <div style="display: flex;">
                <!-- <span v-if="!scope.row.edit">{{ scope.row.timeType | value2lable(optionsOfTimeType) }}</span>
                <el-select v-else v-model="scope.row.timeType" size="mini" placeholder="请选择">
                  <el-option v-for="item in optionsOfTimeType" :key="item.value" :label="item.label" :value="item.value" />
                </el-select> -->
                <span v-if="!scope.row.edit">&nbsp;|&nbsp;{{ scope.row.timeFormat || '--' }}</span>
                <el-input v-else v-model="scope.row.timeFormat" size="mini" placeholder="数据格式">
                  <el-button slot="append" icon="el-icon-printer" @click="handleGenClick(scope)" />
                </el-input>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="班次格式" width="100">
            <template slot-scope="scope">
              <span v-if="!scope.row.edit">{{ scope.row.time }}</span>
              <el-input v-else v-model="scope.row.time" size="mini" placeholder="time" />
            </template>
          </el-table-column>
          <el-table-column label="操作" fixed="right" width="100">
            <template slot-scope="scope">
              <el-button icon="el-icon-edit-outline" type="text" size="small" @click="handleEditClick(scope)" />
              <el-button icon="el-icon-plus" type="text" size="small" @click="handlePlubsClick(scope)" />
              <el-button icon="el-icon-minus" type="text" size="small" @click="handleMinusClick(scope)" />
            </template>
          </el-table-column>
        </el-table>

        <div class="card-footer">
          <el-button v-show="way === 1" size="mini" @click="showTemplateConfig">查看模板配置</el-button>
          <el-button size="mini" @click="drawer2 = !drawer2">查看模板解析结果</el-button>
        </div>
      </el-card>
    </el-form>

    <el-drawer
      title="查看模板配置"
      :visible.sync="drawer1"
      direction="rtl"
    >
      <div class="config-list">
        <div v-for="model in showModels" :key="model.id" class="text item" @click="onModelClick(model)">
          <span>{{ model.name }}</span>
          <i class="el-icon-close" @click="onClickDelModel(model)" />
        </div>
      </div>
    </el-drawer>
    <div
      v-show="drawer2"
      style="transform: translate(0, 10px);"
      title="查看模板解析结果"
    >
      <json-view :data="jsonData" />
    </div>
  </div>
</template>

<script>
import { mapState, mapActions } from 'vuex'
import JsonView from 'vue-json-views'
import * as api from '@/api/model'
import { Upload } from './components'

const EmptyTlpList = [
  { standardCode: '', sheetName: '', axis: '', value: '', branch: '', workshop: '', workarea: '', deviceName: '', deviceCode: '', timeType: '0', timeFormat: '', time: 0, expression: '', edit: true }
]

const createEmptyTlpList = () => {
  return [...EmptyTlpList]
}

const mapOptions = ({ name }) => ({ value: name, label: name })

const value2lable = (value, options) => {
  const option = options.find(o => o.value === value)
  return option && option.label || '--'
}

const WAY_TEMPLATE = 1
const WAY_MANUALLY = 2

export default {
  name: 'ConfigPage',
  filters: {
    value2lable
  },
  components: {
    JsonView,
    Upload
  },
  data() {
    return {
      value: '',
      drawer1: false,
      drawer2: false,
      way: WAY_TEMPLATE,
      form: {
        excelId: 0,
        name: '',
        type: 1,
        list: []
      }
      // manual: {
      //   excelId: 0,
      //   name: '',
      //   type: 0,
      //   list: []
      // }
    }
  },
  computed: {
    ...mapState({
      standardCodes: state => state.dataset.standardCode,
      factory: state => state.dataset.factory,
      factoryName: state => state.user.loginInfo && state.user.loginInfo.factory,
      models: state => state.model.list,
      modelDetail: state => state.model.detail && state.model.detail.tags || [],
      manualList: state => state.model.manualList
    }),
    jsonData() {
      return this.form.list
    },
    showModels() {
      return this.models.filter(m => m.type !== 0)
    },
    manualModel() {
      const list = this.manualList
      return Array.isArray(list) && list.length && list[0]
    },
    factoryIdx() {
      return this.factory && this.factory.findIndex(f => f.name === this.factoryName) || 0
    },
    branchs() {
      const idx = this.factoryIdx
      return this.factory && this.factory[idx] && this.factory[idx].branch || []
    },
    optionsOfStandardCode() {
      return this.standardCodes.map(it => ({ value: it.code, label: it.name }))
    },
    optionsOfBranch() {
      return this.branchs.map(mapOptions)
    },
    disabledSubmitForm() {
      return !this.form.excelId
    },
    optionsOfReportType() {
      return [{
        value: 5,
        label: '班报'
      }, {
        value: 4,
        label: '日报'
      }, {
        value: 3,
        label: '周报'
      }, {
        value: 2,
        label: '月报'
      }, {
        value: 1,
        label: '年报'
      }]
    },
    optionsOfTimeType() {
      return [
        {
          value: '0',
          label: 'none'
        },
        {
          value: '1',
          label: 'table-x'
        },
        {
          value: '2',
          label: 'table-y'
        },
        {
          value: '3',
          label: 'sheet'
        }
      ]
    },
    isTplWay() {
      return this.way === WAY_TEMPLATE
    }
  },
  watch: {
    modelDetail(value) {
      if (Array.isArray(value) && value.length) {
        this.form.list = value.map(it => ({ ...it, edit: false }))
      }
    }
  },
  created() {
    // this.$store.dispatch('dataset/load')
    this.datasetLoad()
    this.fetchManualList()
  },
  methods: {
    ...mapActions({
      datasetLoad: 'dataset/load',
      fetchManualList: 'model/fetchManualList',
      tagValue: 'model/tagValue',
      tagTime: 'model/tagTime',
      submit: 'model/submit',
      fetchDetail: 'model/fetchDetail',
      deleteModel: 'model/deleteModel',
      fetchList: 'model/fetchList'
    }),
    async submitForm(formName) {
      const valid = await this.$refs[formName].validate()
      if (!valid) {
        console.log('error submit!!')
        return false
      }
      try {
        const { excelId, name, type, list } = this.form
        let payload
        if (this.way === WAY_MANUALLY) {
          payload = { excelId, type: 0, data: list }
        } else {
          payload = { excelId, name, type, data: list }
        }
        await this.submit(payload)
        this.$message.success('保存成功')
      } catch (error) {
        console.error('config-page->submitForm', error)
        this.$message.error('保存失败')
      }
    },
    async handleTagvClick({ row }) {
      const excelId = this.form.excelId
      const sheetName = row.sheetName
      const axis = row.axis
      if (excelId && sheetName && axis) {
        const { value } = await api.getTagValue({ excelId, sheetName, axis })
        const list = this.form.list
        const idx = list.findIndex(it => (it.sheetName === sheetName || !it.sheetName) && it.axis === axis)
        if (idx >= 0) {
          list[idx].value = value
        }
      }
      // if (excelId && sheetName && axis) {
      //   this.tagValue({ excelId, sheetName, axis })
      // }
    },
    handleGenClick({ row }) {
      const excelId = this.form.excelId
      const sheetName = row.sheetName
      const axis = row.axis
      const timeFormat = row.timeFormat
      if (excelId && sheetName && axis && timeFormat.includes('%')) {
        this.tagTime({ excelId, sheetName, axis, timeFormat })
      }
    },
    handleEditClick({ row }) {
      row.edit = !row.edit
    },
    handlePlubsClick({ row, $index }) {
      const per = this.form.list.filter((_, i) => i <= $index)
      const fer = this.form.list.filter((_, i) => i > $index)
      const item = { ...row, edit: false }
      this.form.list = [...per, item, ...fer]
    },
    handleMinusClick({ row, $index }) {
      const per = this.form.list.filter((_, i) => i < $index)
      const fer = this.form.list.filter((_, i) => i > $index)
      this.form.list = [...per, ...fer]
    },
    onUploadSucceed(data) {
      this.form.excelId = data.excelId
      this.form.name = ''
      // this.form.type = '1'
      this.form.list = createEmptyTlpList()
    },
    workshops({ branch }) {
      const item = this.branchs.find(it => it.name === branch)
      return item && item.workshop || []
    },
    optionsOfWorkshop(row) {
      return this.workshops(row).map(mapOptions)
    },
    workareas({ branch, workshop }) {
      const item = this.workshops({ branch }).find(it => it.name === workshop)
      return item && item.workarea || []
    },
    optionsOfWorkarea(row) {
      return this.workareas(row).map(mapOptions)
    },
    devices({ branch, workshop, workarea }) {
      const item = this.workareas({ branch, workshop }).find(it => it.name === workarea)
      return item && item.device || []
    },
    optionsOfDevices(row) {
      return this.devices(row).map(mapOptions)
    },
    onModelClick(model) {
      const excelId = model.id
      this.form.excelId = excelId
      this.form.name = model.name
      this.form.type = model.type
      this.fetchDetail(excelId)
    },
    async onClickDelModel(model) {
      try {
        await this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
      } catch (error) {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
        return
      }
      try {
        if (model && model.id) {
          this.deleteModel(model.id)
        }
      } catch (error) {
        console.error('删除模板', error)
        this.$message.error('删除失败')
      }
    },
    showTemplateConfig() {
      this.drawer1 = true
      this.fetchList()
    },
    onWayChange() {
      if (this.way === WAY_MANUALLY) {
        this.onModelClick(this.manualModel)
      } else {
        this.form.list = []
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.config {
  &-container {
    margin: 16px;
    .box-card {
      /* min-height: 580px; */
      .header__item{
        display: inline-flex;
        width: 220px;
        margin-left: 16px;
        .label {
          width: 90px;
          font-size: 14px;
          line-height: 40px;
        }
        /deep/ .el-input {
          line-height: 40px;
        }
      }
      .header__left {
        float: left;
      }
      .header__right {
        float: right;
        padding: 3px 0;
        line-height: 40px;
      }
      .header-divider {
        height: 1.2em;
        margin: 8px 8px;
      }
      .row-text {
        button {
          display: none;
        }
        &:hover {
          button {
            display: inline-block;
          }
        }
      }
      .card-footer {
        margin-top: 32px;
        /* position: absolute;
        bottom: 40px; */
      }
      .header-upload {
        display: inline-block;
        /deep/ .el-upload-list {
          display: inline-block;
        }
      }
      .column-coordinate {
        &:hover {
          i {
            display: inline-block;
          }
        }
        i {
          margin-left: 8px;
          cursor: pointer;
          line-height: 28px;
          display: none;
        }
      }
    }
  }
  &-text {
    font-size: 30px;
    line-height: 46px;
  }
}
.config-list {
  padding: 0 20px;
  .text {
    font-size: 14px;
  }
  .item {
    position: relative;
    cursor: pointer;
    margin-bottom: 18px;
    padding: 10px 0;
    &:hover {
      background-color: #F5F7FA;
      color: #66b1ff;
      i {
        display: inline-block;
      }
    }
    i {
      display: none;
      position: absolute;
      top: 8px;
      right: 8px;
      cursor: pointer;
      opacity: .75;
      color: #606266;
    }
  }
}

</style>
